/*
 *
 */
package org.jiscinvolve.astrodabis.barberry.common.inport;

import java.net.URI;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.junit.Test;
import org.junit.After;
import org.junit.Before;
import static org.junit.Assert.*;

import java.util.Iterator;
import java.io.FileInputStream;

import org.springframework.beans.factory.annotation.Autowired;  

import org.jiscinvolve.astrodabis.barberry.common.core.Job;
import org.jiscinvolve.astrodabis.barberry.common.core.Tagged;

import org.jiscinvolve.astrodabis.barberry.common.core.CoreTestBase;
import org.jiscinvolve.astrodabis.barberry.common.data.DataTestBase;

import org.jiscinvolve.astrodabis.barberry.common.data.RowTag;
import org.jiscinvolve.astrodabis.barberry.common.data.JoinTag;

import org.jiscinvolve.astrodabis.barberry.common.data.TapRow;
import org.jiscinvolve.astrodabis.barberry.common.data.TapTable;
import org.jiscinvolve.astrodabis.barberry.common.data.TapColumn;
import org.jiscinvolve.astrodabis.barberry.common.data.TapService;

import org.jiscinvolve.astrodabis.barberry.common.inport.votable.VOTableStarTableParser;
import org.jiscinvolve.astrodabis.barberry.common.inport.startable.TaggedStarTableParser;
import org.jiscinvolve.astrodabis.barberry.common.inport.startable.UnknownColumnException;

/*
 *
 */
public class RowTagParserTestCase
extends DataTestBase
    {

    /**
     * Our debug logger.
     * 
     */
    private static Log log = LogFactory.getLog(RowTagParserTestCase.class);

    protected TapService service ;
    protected TapTable   tableone ;
    protected TapColumn  columnone ;

    @Before
    public void before()
        {
        super.before();
        log.debug("RowTagParserTestCase.before()");

        service = womble().services().create(
            unique(
                URI.create(
                    "ivo://org.astrodabis.test/service/"
                    )
                ),
            "test-service"
            );
        tableone = service.tables().create(
            "test-table-one"
            );
        columnone = tableone.columns().create(
            "test-column-one"
            );
        }

    /**
     * Check we get the right number of rows for a single table.
     *
     */
    @Test
    public void test000()
    throws Exception
        {

        Iterator<Tagged> parser = new TaggedStarTableParser(
            account().jobs().create(
                new Job.Bean(
                    "job-name",
                    "job-text",
                    columnone
                    )
                ),
            new VOTableStarTableParser(
                new FileInputStream(
                    "src/test/data/join-test-000.xml"
                    )
                )
            );

        int count = 0 ;
        while(parser.hasNext())
            {
            log.debug(
                parser.next()
                );
            count++;
            }
        assertEquals(
            4,
            count
            );
        }

    /**
     * Check we get the right number of rows for multiple tables.
     *
     */
    @Test
    public void test001()
    throws Exception
        {
        Iterator<Tagged> parser = new TaggedStarTableParser(
            account().jobs().create(
                new Job.Bean(
                    "job-name",
                    "job-text",
                    columnone
                    )
                ),
            new VOTableStarTableParser(
                new FileInputStream(
                    "src/test/data/join-test-001.xml"
                    )
                )
            );

        int count = 0 ;
        while(parser.hasNext())
            {
            log.debug(
                parser.next()
                );
            count++;
            }
        assertEquals(
            64,
            count
            );
        }

    /**
     * Check we get the right columns based on column name.
     *
     */
    @Test
    public void test002()
    throws Exception
        {
        Iterator<Tagged> parser = new TaggedStarTableParser(
            account().jobs().create(
                new Job.Bean(
                    "job-name",
                    "job-text",
                    columnone
                    )
                ),
            new VOTableStarTableParser(
                new FileInputStream(
                    "src/test/data/join-test-002.xml"
                    )
                )
            );

        int count = 0 ;
        while(parser.hasNext())
            {
            Tagged tagged = parser.next();
            assertTrue(
                (tagged instanceof RowTag)
                );
            RowTag rowtag = (RowTag) tagged ;
            log.debug(
                rowtag
                );
            assertEquals(
                "row-one",
                rowtag.row().value()
                );
            count++;
            }
        assertEquals(
            4,
            count
            );
        }

    /**
     * Check we fail if we can't match the column names.
     *
     */
    @Test
    public void test003a()
    throws Exception
        {
        Iterator<Tagged> parser = new TaggedStarTableParser(
            account().jobs().create(
                new Job.Bean(
                    "job-name",
                    "job-text",
                    columnone
                    )
                ),
            new VOTableStarTableParser(
                new FileInputStream(
                    "src/test/data/join-test-003.xml"
                    )
                )
            );

        try {
            log.debug(
                parser.next()
                );
            fail("Expected UnknownColumnException");
            }
        catch (UnknownColumnException ouch)
            {
            }
        }

    /**
     * Check we get the right columns using column aliases.
     *
     */
    @Test
    public void test003b()
    throws Exception
        {
        Iterator<Tagged> parser = new TaggedStarTableParser(
            account().jobs().create(
                new Job.Bean(
                    "job-name",
                    "job-text",
                    columnone,
                    "other-column-one"
                    )
                ),
            new VOTableStarTableParser(
                new FileInputStream(
                    "src/test/data/join-test-003.xml"
                    )
                )
            );

        int count = 0 ;
        while(parser.hasNext())
            {
            Tagged tagged = parser.next();
            assertTrue(
                (tagged instanceof RowTag)
                );
            RowTag rowtag = (RowTag) tagged ;
            log.debug(
                rowtag
                );
            assertEquals(
                "row-one",
                rowtag.row().value()
                );
            count++;
            }
        assertEquals(
            4,
            count
            );
        }

    /**
     * Check we get the right columns with the names swapped.
     *
     */
    @Test
    public void test003c()
    throws Exception
        {
        Iterator<Tagged> parser = new TaggedStarTableParser(
            account().jobs().create(
                new Job.Bean(
                    "job-name",
                    "job-text",
                    columnone,
                    "other-column-two"
                    )
                ),
            new VOTableStarTableParser(
                new FileInputStream(
                    "src/test/data/join-test-003.xml"
                    )
                )
            );

        int count = 0 ;
        while(parser.hasNext())
            {
            Tagged tagged = parser.next();
            assertTrue(
                (tagged instanceof RowTag)
                );
            RowTag rowtag = (RowTag) tagged ;
            log.debug(
                rowtag
                );
            assertEquals(
                "row-two",
                rowtag.row().value()
                );
            count++;
            }
        assertEquals(
            4,
            count
            );
        }

    /**
     * Check we get the right number of rows with empty tables.
     *
     */
    @Test
    public void test004()
    throws Exception
        {
        Iterator<Tagged> parser = new TaggedStarTableParser(
            account().jobs().create(
                new Job.Bean(
                    "job-name",
                    "job-text",
                    columnone
                    )
                ),
            new VOTableStarTableParser(
                new FileInputStream(
                    "src/test/data/join-test-004.xml"
                    )
                )
            );

        int count = 0 ;
        while(parser.hasNext())
            {
            log.debug(
                parser.next()
                );
            count++;
            }
        assertEquals(
            8,
            count
            );
        }

    }

